package com.huike.report.service.impl;

import com.huike.business.mapper.TbBusinessMapper;
import com.huike.clues.domain.TbActivity;
import com.huike.clues.domain.TbClue;
import com.huike.clues.domain.vo.IndexStatisticsVo;
import com.huike.clues.mapper.SysDeptMapper;
import com.huike.clues.mapper.SysDictDataMapper;
import com.huike.clues.mapper.TbActivityMapper;
import com.huike.clues.mapper.TbClueMapper;
import com.huike.common.core.domain.entity.SysDeptDTO;
import com.huike.common.utils.SecurityUtils;
import com.huike.contract.domain.TbContract;
import com.huike.contract.mapper.TbContractMapper;
import com.huike.report.domain.vo.*;
import com.huike.report.mapper.ReportMapper;
import com.huike.report.service.ReportService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {
    @Resource
    private ReportMapper reportMapper;
    @Resource
    private TbContractMapper tbContractMapper;
    @Resource
    private SysDictDataMapper sysDictDataMapper;
    @Resource
    private TbActivityMapper tbActivityMapper;
    @Resource
    private TbClueMapper tbClueMapper;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private TbBusinessMapper tbBusinessMapper;

    /**
     * 客户统计新增客户数报表
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public LineChartVo contractStatistics(String beginCreateTime, String endCreateTime) {
        //创建一个空的返回集结果
        LineChartVo vo = new LineChartVo();
        try {
            List<String> timeList = findDates(beginCreateTime, endCreateTime);
            vo.setxAxis(timeList);
            ArrayList<LineSeriesVo> series = new ArrayList<>();
            List<Map<String,Object>> statistics = tbContractMapper.contractStatistics(beginCreateTime,endCreateTime);
            LineSeriesVo lineSeriesVo1 = new LineSeriesVo();
            lineSeriesVo1.setName("新增客户数");
            LineSeriesVo lineSeriesVo2 = new LineSeriesVo();
            lineSeriesVo2.setName("客户总数");
            int sum = 0;

            for (String s : timeList) {
                Optional optional = statistics.stream().filter(d -> d.get("dd").equals(s)).findFirst();
                if (optional.isPresent()){
                    Map<String,Object> cuurentData = (Map<String, Object>) optional.get();
                    lineSeriesVo1.getData().add(cuurentData.get("num"));
                    sum += Integer.parseInt(cuurentData.get("num").toString());
                }else {
                    lineSeriesVo1.getData().add(0);
                }
                lineSeriesVo2.getData().add(sum);
            }
            series.add(lineSeriesVo1);
            series.add(lineSeriesVo2);
            vo.setSeries(series);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return vo;
    }

    /**
     * 客户统计学科分布统计报表
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String,Object>> subjectStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String,Object>> data = tbContractMapper.subjectStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue = (String) datum.get("subject");
            String lable = sysDictDataMapper.selectDictLabel("course_subject",subjectValue);
            datum.put("subject",lable);
        }
        return data;
    }

    /**
     * 客户统计明细列表
     * @param contract
     * @return
     */
    @Override
    public List<TbContract> contractStatisticsList(TbContract contract) {
        return tbContractMapper.selectTbContractList(contract);
    }



    /**
     * 销售统计报表
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public LineChartVo salesStatistics(String beginCreateTime, String endCreateTime) {
        LineChartVo vo = new LineChartVo();
        try {
            List<String> timeList = findDates(beginCreateTime, endCreateTime);
            vo.setxAxis(timeList);
            ArrayList<LineSeriesVo> series = new ArrayList<>();
            List<Map<String,Object>> statistics = tbContractMapper.salesStatistics(beginCreateTime,endCreateTime);
            LineSeriesVo lineSeriesVo = new LineSeriesVo();
            lineSeriesVo.setName("销售统计");
            int sum =0;
            for (String s : timeList) {
                Optional optional = statistics.stream().filter(d -> d.get("dd").equals(s)).findFirst();
                if (optional.isPresent()){
                    Map<String,Object> cuurentData = (Map<String, Object>) optional.get();
                    lineSeriesVo.getData().add(cuurentData.get("sales"));
                }else {
                    lineSeriesVo.getData().add(0);
                }
            }
            series.add(lineSeriesVo);
            vo.setSeries(series);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return vo;
    }

    /**
     * 按照归属渠道统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> channelStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String,Object>> data = tbContractMapper.channelStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue = (String) datum.get("channel");
            if (subjectValue != null){
                String lable = sysDictDataMapper.selectDictLabel("clues_item",subjectValue);
                datum.put("channel",lable);
            }
        }
        return data;
    }

    /**
     * 按照归属部门统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String,Object>> deptStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String,Object>> data = tbContractMapper.deptStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            Long deptId = (Long) datum.get("dept_id");
            if (deptId != null){
                SysDeptDTO dept = sysDeptMapper.selectDeptById(deptId);
                datum.put("deptName",dept.getDeptName());
            }
        }
        return data;
    }

    /**
     * 按照归属人统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> ownerShipStatisticsList(String beginCreateTime, String endCreateTime) {
        return tbContractMapper.ownerShipStatistics(beginCreateTime,endCreateTime);
    }



    /**
     * 按照新增线索统计数量
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public LineChartVo cluesStatistics(String beginCreateTime, String endCreateTime) {
        LineChartVo vo = new LineChartVo();
        try {
            List<String> timeList = findDates(beginCreateTime, endCreateTime);
            vo.setxAxis(timeList);
            ArrayList<LineSeriesVo> series = new ArrayList<>();
            List<Map<String,Object>> statistics = tbClueMapper.cluesStatistics(beginCreateTime,endCreateTime);
            LineSeriesVo lineSeriesVo1 = new LineSeriesVo();
            lineSeriesVo1.setName("新增线索数量");
            LineSeriesVo lineSeriesVo2 = new LineSeriesVo();
            lineSeriesVo2.setName("线索总数量");
            int sum =0;
            for (String s : timeList) {
                Optional optional = statistics.stream().filter(d -> d.get("dd").equals(s)).findFirst();
                if (optional.isPresent()){
                    Map<String,Object> cuurentData = (Map<String, Object>) optional.get();
                    lineSeriesVo1.getData().add(cuurentData.get("num"));
                    sum += Integer.parseInt(cuurentData.get("num").toString());
                }else {
                    lineSeriesVo1.getData().add(0);
                }
                lineSeriesVo2.getData().add(sum);
            }
            series.add(lineSeriesVo1);
            series.add(lineSeriesVo2);
            vo.setSeries(series);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return vo;
    }

    /**
     * 线索统计线索转换率报表
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public VulnerabilityMapVo getVulnerabilityMap(String beginCreateTime, String endCreateTime) {
        VulnerabilityMapVo vo = new VulnerabilityMapVo();
        //线索数
        vo.setCluesNums(tbClueMapper.countAllClues(beginCreateTime,endCreateTime));
        //有效线索数
        vo.setEffectiveCluesNums(tbClueMapper.effectiveCluesNums(beginCreateTime,endCreateTime));
        //商机数
        vo.setBusinessNums(tbBusinessMapper.businessNumsFromClue(beginCreateTime,endCreateTime));
        //合同数
        vo.setContractNums(tbContractMapper.contractNumsFromBusiness(beginCreateTime,endCreateTime));
        return vo;
    }

    /**
     * 线索统计明细列表
     * @param tbClue
     * @return
     */
    @Override
    public List<TbClue> cluesStatisticsList(TbClue tbClue) {
        return tbClueMapper.selectTbClueForReport(tbClue);
    }


    /**
     * 渠道统计
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String,Object>> chanelStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String,Object>> data = tbContractMapper.chanelStatistics(beginCreateTime,endCreateTime);
        for (Map<String,Object> datum : data) {
            String subjectValue = (String) datum.get("channel");
            String lable = sysDictDataMapper.selectDictLabel("clues_item", subjectValue);
            datum.put("channel",lable);
        }
        return data;
    }

    /**
     * 渠道统计-活动统计
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String,Object>> activityStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data= tbContractMapper.activityStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            Long activityId= (Long) datum.get("activity_id");
            TbActivity tbActivity = tbActivityMapper.selectTbActivityById(activityId);
            if(tbActivity==null){
                datum.put("activity", "其他");
            }else{
                datum.put("activity", tbActivity.getName());
            }
        }
        return data;
    }

    /**
     * 渠道统计活动明细列表
     * @param query
     * @return
     */
    @Override
    public List<ActivityStatisticsVo> activityStatisticsList(TbActivity query) {
        query.setStatus("2");
        List<TbActivity> activities= tbActivityMapper.selectTbActivityList(query);
        Map<String, Object> timeMap = query.getParams();
        List<ActivityStatisticsVo> list=new ArrayList<>();
        for (TbActivity activity : activities) {
            ActivityStatisticsVo dto = new ActivityStatisticsVo();
            BeanUtils.copyProperties(activity, dto);
            TbClue tbClue = new TbClue();
            tbClue.setActivityId(activity.getId());
            tbClue.setChannel(activity.getChannel());
            tbClue.setParams(timeMap);
            Map<String, Object> clueCount = tbClueMapper.countByActivity(tbClue);
            if (clueCount != null) {
                dto.setCluesNum(Integer.parseInt(clueCount.get("total").toString()));
                if(clueCount.get("falseClues")!=null){
                    dto.setFalseCluesNum(Integer.parseInt(clueCount.get("falseClues").toString()));
                }
                if (clueCount.get("toBusiness") != null) {
                    dto.setBusinessNum(Integer.parseInt(clueCount.get("toBusiness").toString()));
                }
            }
            TbContract tbContract = new TbContract();
            tbContract.setChannel(activity.getChannel());
            tbContract.setActivityId(activity.getId());
            tbContract.setParams(timeMap);
            Map<String, Object> contractCount = tbContractMapper.countByActivity(tbContract);
            if (contractCount != null) {
                dto.setCustomersNum(Integer.parseInt(contractCount.get("customersNum").toString()));
                if(contractCount.get("amount")==null) {
                    dto.setAmount(0d);
                }else {
                    dto.setAmount((Double) contractCount.get("amount"));
                }
                if(contractCount.get("cost")==null) {
                    dto.setCost(0d);
                }else {
                    dto.setCost((Double) contractCount.get("cost"));
                }

            }
            list.add(dto);
        }
        return list;
    }

    /**
     * 基础数据统计接口
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public IndexBaseInfoVO getBaseInfo(String beginCreateTime, String endCreateTime) {
        //创建一个空的结果集对象
        IndexBaseInfoVO vo = new IndexBaseInfoVO();
        //获取用户名
        String username = SecurityUtils.getUsername();
        //线索数目
        Integer cluesNum = reportMapper.getCluesNum(beginCreateTime,endCreateTime,username);
        //商机数目
        Integer businessNum = reportMapper.getBusinessNum(beginCreateTime,endCreateTime,username);
        //合同数目
        Integer contractNum = reportMapper.getContractNum(beginCreateTime,endCreateTime,username);
        //销售金额
        Double salesAmount = reportMapper.getSalesAmount(beginCreateTime,endCreateTime,username);

        //封装数据
        vo.setCluesNum(cluesNum);
        vo.setBusinessNum(businessNum);
        vo.setContractNum(contractNum);
        vo.setSalesAmount(salesAmount);
        return vo;
    }

    /**
     * 获取今日简报数据
     * @return
     */
    @Override
    public IndexTodayInfoVO getTodayInfo(String today) {
        //创建一个空的结果集对象
        IndexTodayInfoVO vo = new IndexTodayInfoVO();
        //获取用户名
        String username = SecurityUtils.getUsername();
        //今日线索数量
        vo.setTodayCluesNum(reportMapper.getTodayCluesNum(today,username));
        //今日商机数量
        vo.setTodayBusinessNum(reportMapper.getTodayBusinessNum(today,username));
        //今日合同数量
        vo.setTodayContractNum(reportMapper.getTodayContractNum(today,username));
        //今日合同金额
        vo.setTodaySalesAmount(reportMapper.getTodaySalesAmount(today,username));

        return vo;
    }

    /**
     * 获取待办数据
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public IndexTodoInfoVO getTodoInfo(String beginCreateTime, String endCreateTime) {
        //创建一个空的结果集对象
        IndexTodoInfoVO vo = new IndexTodoInfoVO();
        //获取用户名
        String username = SecurityUtils.getUsername();
        //待跟进线索数目
        vo.setTofollowedCluesNum(reportMapper.getTofollowedCluesNum(beginCreateTime,endCreateTime,username));
        //待跟进商机数目
        vo.setTofollowedBusinessNum(reportMapper.getTofollowedBusinessNum(beginCreateTime,endCreateTime,username));
        //待分配线索数目
        vo.setToallocatedCluesNum(reportMapper.getToallocatedCluesNum(beginCreateTime,endCreateTime,username));
        //待分配商机数目
        vo.setToallocatedBusinessNum(reportMapper.getToallocatedBusinessNum(beginCreateTime,endCreateTime,username));
        return vo;
    }

    /**
     * 线索转化成龙虎榜
     * @param indexStatisticsVo
     * @return
     */
    @Override
    public List<Map<String, Object>> salesStatistic(IndexStatisticsVo indexStatisticsVo) {
        int allclues = tbClueMapper.countAllClues(indexStatisticsVo.getBeginCreateTime(),indexStatisticsVo.getEndCreateTime());
        List<Map<String,Object>> list = tbClueMapper.countAllClueByUser(indexStatisticsVo);
        //计算转换率
        for (Map<String, Object> map : list) {
            Long num = (Long) map.get("num");
            map.put("radio",getRadio(allclues,num));
        }
        return list;
    }

    /**
     * 商机转换龙虎榜
     * @param request
     * @return
     */
    @Override
    public List<Map<String, Object>> businessChangeStatistics(IndexStatisticsVo request) {
        int allBusiness = tbBusinessMapper.countAllBusiness(request.getBeginCreateTime(),request.getEndCreateTime());
        List<Map<String,Object>> list = tbBusinessMapper.countAllContractByUser(request);
        for (Map<String, Object> map : list) {
            Long num = (Long) map.get("num");
            map.put("radio",getRadio(allBusiness,num));
        }
        return list;
    }

    private BigDecimal getRadio(Integer all, Long num) {
        if (all.intValue() == 0){
            return new BigDecimal(0);
        }
        BigDecimal numBigDecimal = new BigDecimal(num);
        BigDecimal allBigDecimal = new BigDecimal(all);
        //保留4位小数，四舍五入
        BigDecimal divide = numBigDecimal.divide(allBigDecimal,4,BigDecimal.ROUND_HALF_UP);
        //转化成百分比
        return divide.multiply(new BigDecimal(100));
    }

    public static List<String> findDates(String beginTime,String endTime) throws ParseException {
        //创建一个空的返回集合
        ArrayList<String> allDate = new ArrayList<>();
        //设置日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //将日期字符串转换成指定格式
        Date dBegin = sdf.parse(beginTime);
        Date dEnd = sdf.parse(endTime);
        //将格式化后的日期存入集合
        allDate.add(sdf.format(dBegin));
        Calendar calBegin = Calendar.getInstance();
        //使用给定的Date设置此Calendar的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(dEnd);
        //测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())){
            //根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH,1);
            allDate.add(sdf.format(calBegin.getTime()));
        }
        return allDate;
    }
}
